import { Calendar, Popup } from "@taroify/core"
import { CalendarType } from "@taroify/core/calendar/calendar.shared"
import React, { useEffect, useState } from 'react'
import { View } from '@tarojs/components'
import { getPageInfo } from "@/path/acrossAPI";
import { renderGeneralModal } from "@/components/generalAnchor/data"
import dayjs from "dayjs";
import './index.scss'

type TypeOptions = {
  /**标题 */
  title?: React.ReactNode,
  /**	选择类型:single 表示选择单个日期，multiple 表示选择多个日期，range 表示选择日期区间 @default single */
  type?: CalendarType,
  /**是否展示日历副标题（年月） @default false */
  subtitle?: boolean
  /**可选择的最小日期	Date	当前日期的前六个月 */
  min?: Date,
  /**可选择的最大日期	Date	当前日期 */
  max?: Date,
  /**	默认选中的日期，type 为 multiple 或 range 时为数组，传入 null 表示默认不选择	Date | Date[] | null	今天 */
  defaultValue?: Date | Date[],
  /**	选中的日期，type 为 multiple 或 range 时为数组，传入 null 表示默认不选择	Date | Date[]	今天 */
  value?: Date | Date[],
  /**Get the formatted date according to the string of tokens passed in.
To escape characters, wrap them in square brackets (e.g. [MM]).
dayjs().format()// => current date in ISO8601, without fraction seconds e.g. '2020-04-02T08:02:17-05:00'
dayjs('2019-01-25').format('[YYYYescape] YYYY-MM-DDTHH:mm:ssZ[Z]')// 'YYYYescape 2019-01-25T00:00:00-02:00Z'
dayjs('2019-01-25').format('DD/MM/YYYY') // '25/01/2019'
Docs: https://day.js.org/docs/en/display/format */
  template?: string,
  /**日期格式化函数	(day: Calendar.DayObject) => Calendar.DayObject */
  formatter?: (day: Calendar.DayObject) => Calendar.DayObject,
  /**组件初始化的时候触发此函数 */
  onInit?: (p: { onAffirm: (param?: Date | Date[]) => void, onCancel: () => void, setLoading: React.Dispatch<React.SetStateAction<boolean>> }) => void,
  /**拦截点击确认按钮 传入此函数将拦截确认按钮并触发此函数 */
  onPrevent?: (p: { onAffirm: (param?: Date | Date[]) => void, onCancel: () => void, setLoading: React.Dispatch<React.SetStateAction<boolean>>, params: any }) => void,
  /**确认按钮文字 @default "确认" */
  confirmText?: React.ReactNode,
  /**是否在点击遮罩层后关闭 @default true */
  closeable?: boolean
  placement?: "top" | "right" | "bottom" | "left",
}

function Index(props: TypeOptions & { reject: () => void, resolve: (p: any) => void }) {
  const [show, setShow] = useState(false)
  const [loading, setLoading] = useState(false)
  /**取消 */
  function onCancel() {
    props.reject()
    setShow(false);
  }
  function onResolve(ev: any) {
    const _data = { current: ev }
    if (props.template) {
      if (ev instanceof Array) {
        _data.current = ev.map(v => {
          return dayjs(v).format(props.template)
        })
      } else {
        _data.current = dayjs(ev).format(props.template)
      }
    }

    function run(param?: any) {
      props.resolve(param || _data.current)
      setShow(false);
    }
    if (typeof props.onPrevent === "function") {
      props.onPrevent({ onAffirm: run, onCancel, setLoading, params: _data.current })
      return
    }
    run()
  }
  useEffect(() => {
    setShow(true);
    if (typeof props.onInit === "function") {
      props.onInit({ onAffirm: onResolve, onCancel, setLoading })
    }
  }, [])
  function getDayAgo(number = 6) {
    const today = new Date();
    const sixMonthsAgo = new Date();
    sixMonthsAgo.setMonth(today.getMonth() - number);
    return sixMonthsAgo
  }
  return <View className="xm-dialog-box">
    <Popup style={{ height: "80%" }} open={show} onClose={onCancel} rounded placement="bottom">
      <Popup.Backdrop closeable={props.closeable}></Popup.Backdrop>
      <Calendar type={props.type} onConfirm={onResolve} title={props.title} subtitle={props.subtitle || false}
        formatter={props.formatter} min={props.min || getDayAgo()} max={props.max || new Date()} defaultValue={props.defaultValue} value={props.value}>
        <Calendar.Footer>
          <Calendar.Button type="confirm" color="primary" loading={loading}>{props.confirmText}</Calendar.Button>
        </Calendar.Footer>
      </Calendar>
    </Popup>
  </View>
}

export const NodeId = "dialog-calendar-id"
export default function (params: TypeOptions): Promise<Date | Date[]> {
  return new Promise((resolve, reject) => {
    const nowPageID = getPageInfo().routeID;
    function onClear() {
      return new Promise((resolve) => {
        setTimeout(() => {
          renderGeneralModal({
            nodeId: NodeId,
            node: null,
            nowPageID
          })
          resolve(true)
        }, 300);
      })
    }
    function onResolve(ev: Date | Date[]) {
      onClear().then(() => {
        resolve(ev)
      })
    }
    function onReject() {
      onClear().then(() => {
        reject()
      })
    }
    renderGeneralModal({
      nodeId: NodeId,
      node: <Index {...params} resolve={onResolve} reject={onReject} />,
      nowPageID
    })
  })
}